package com.ruoyi.analytics.service.impl;

import com.ruoyi.analytics.domain.AnalyticsEvent;
import com.ruoyi.analytics.mapper.AnalyticsEventRepository;
import com.ruoyi.analytics.service.IAnalyticsEventService;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class AnalyticsEventServiceImpl implements IAnalyticsEventService {

    @Autowired
    private AnalyticsEventRepository analyticsEventRepository;

    @Autowired
    private MongoTemplate mongoTemplate; // 使用MongoTemplate进行复杂查询

    /**
     * 使用@Async注解，使其成为一个异步方法。
     * 调用此方法会立即返回，任务会在线程池中执行。
     * 这可以大大提高上报接口的响应速度。
     * 需要在启动类上加 @EnableAsync
     */
    @Async
    @Override
    public void saveEvent(AnalyticsEvent event) {
        // 在这里可以增加一些业务逻辑，如补充服务器时间等
        analyticsEventRepository.save(event);
    }

    @Override
    public TableDataInfo queryEventList(Map<String, Object> queryParams) {
        // 1. 构建动态查询条件
        Query query = new Query();
        Criteria criteria = new Criteria();

        // 事件名称查询
        if (StringUtils.isNotEmpty((String) queryParams.get("eventName"))) {
            criteria.and("event_name").is(queryParams.get("eventName"));
        }
        // 用户ID查询
        if (StringUtils.isNotEmpty((String) queryParams.get("userId"))) {
            criteria.and("user.user_id").is(queryParams.get("userId"));
        }
        // 时间范围查询
        String beginTime = (String) queryParams.get("beginTime"); // 格式如 "2023-01-01 00:00:00"
        String endTime = (String) queryParams.get("endTime");     // 格式如 "2023-01-31 23:59:59"
        if (StringUtils.isNotEmpty(beginTime) && StringUtils.isNotEmpty(endTime)) {
            // 注意：这里假设前端传来的event_time是ISO格式字符串，可以直接比较
            criteria.and("event_time").gte(beginTime).lte(endTime);
        }
        query.addCriteria(criteria);

        // 2. 处理分页
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();

        // 统计总数
        long count = mongoTemplate.count(query, AnalyticsEvent.class);
        if (count <= 0) {
            return new TableDataInfo();
        }

        // 3. 处理排序 (按事件时间降序)
        query.with(Sort.by(Sort.Direction.DESC, "event_time"));

        // 4. 设置分页参数
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
        query.with(pageable);

        // 5. 执行查询
        List<AnalyticsEvent> list = mongoTemplate.find(query, AnalyticsEvent.class);

        // 6. 封装成若依的TableDataInfo对象返回
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(0); // 成功状态码
        rspData.setRows(list);
        rspData.setTotal(count);
        return rspData;
    }
}